/*
 * FilePath     : \src\utils\directives.ts
 * Author       : 杨欣欣
 * Date         : 2023-08-08 17:02
 * LastEditors  : 胡长攀
 * LastEditTime : 2024-12-17 14:15
 * Description  :
 * CodeIterationRecord:
 */
import common from "@/utils/common";
import dateTimeUtil from "@/utils/datetimeUtil";
import Sortable from "sortablejs";
import { nextTick } from "vue";

// 格式化时间指令 format不传，默认不带秒，value和type必须传
// <span v-formatTime="{ value: now, type: 'dateTime', format: 'yyyy-MM-dd hh:mm:ss' }"></span>
const formatTime = (el: any, binding: any) => {
  let format = binding.value.format;
  let result = "";
  if (binding.value) {
    if (binding.value.type && binding.value.value) {
      // 判断类型
      if (binding.value.type === "date" && !binding.value.format) {
        format = "yyyy-MM-dd";
      } else if (binding.value.type === "time" && !binding.value.format) {
        format = "hh:mm";
      } else if (binding.value.type === "dateTime" && !binding.value.format) {
        format = "yyyy-MM-dd hh:mm";
      }
      result = dateTimeUtil.formatDate(binding.value.value, format);
    }
    el.innerHTML = "";
    el.innerHTML = result;
  }
};

/**
 * @description: 检核权限
 * @param el
 * @param binding
 * @return
 */
const checkPermission = (el: any, binding: any) => {
  const session = common.session("session");
  const componentList = session?.componentList;
  const currRouterListID = session?.currRouterListID;
  const componentID = binding.value;
  const controlerType = binding.arg;
  if (componentList && componentID) {
    // 根据当前路由ID和组件ID查找组件
    const component = componentList.find((component: any) => {
      return (
        component.componentListID === componentID && component.routerListID === currRouterListID && component.controlerType == controlerType
      );
    });
    // 如果找不到组件且组件类为B(按钮)或者是DL(下拉框)，则移除当前组件
    // 如果找到组件且组件状态为不显示，则移除当前组件
    if ((!component && (controlerType === "B" || controlerType === "DL")) || component?.status === 0) {
      // 自定义组件使用removeChild会白屏，改为隐藏
      // el.parentNode.removeChild(el);
      el.style["display"] = "none";
    }
  }
};

/**
 * @description: 修复表格单元格高度
 * @param el
 * @param binding
 * @return
 */
const fixCellHeight = async (el: any, binding: any) => {
  await nextTick(() => {
    const tr = el.closest(".el-table__row");
    if (!tr) {
      return;
    }
    let contentArr = Array.from(tr.getElementsByClassName(binding.value), (item) => item as Element);
    if (!contentArr?.length) {
      return;
    }
    let maxHeight = contentArr.reduce((max, td) => {
      let height: number = (td as HTMLElement).offsetHeight;
      return height > max ? height : max;
    }, binding.arg || 0);
    contentArr.forEach((element: Element) => {
      (element as HTMLElement).style.minHeight = `${maxHeight}px`;
    });
  });
};
/**
 * description:解决多选下拉框高度不能撑开问题
 * param {any} el
 * return {*}
 */
const fixMultipleSelectHeight = async (el: any) => {
  await nextTick(() => {
    const tagSpan = el.getElementsByClassName("el-select__tags")?.[0];
    const input = el.getElementsByClassName("el-input__inner")?.[0];
    const inputWrapper = el.getElementsByClassName("el-input--suffix")?.[0];
    if (!tagSpan || !input || !inputWrapper) {
      return;
    }
    if (tagSpan.offsetHeight === 0) {
      return;
    }
    input.style.height = tagSpan.offsetHeight + 15 + "px";
    inputWrapper.style.height = "auto";
    inputWrapper.style.setProperty("height", "auto", "important");
  });
};

/**
 * @description: 拖拽排序
 * @param el
 * @param binding
 * @return
 */
const dragSort = async (el: any, binding: any) => {
  nextTick(() => {
    let element = binding.value.el ? el.querySelector(binding.value.el) || el : el;
    Sortable.create(element, {
      disabled: false,
      group: {
        pull: false,
        put: false
      },
      handle: binding.value.handleClass || "",
      onEnd: (evt: any) => {
        const { newIndex, oldIndex } = evt;
        if (binding.value.callBack && typeof binding.value.callBack === "function") {
          binding.value.callBack(newIndex, oldIndex);
        }
      }
    });
  });
};

const visibilityHidden = async (el: any, binding: any) => {
  nextTick(() => {
    el.style.visibility = !binding.value ? "hidden" : "visible";
  });
};

// 日期时间格式化
const formatTimeDirective = {
  mounted(el: any, binding: any) {
    formatTime(el, binding);
  },
  updated(el: any, binding: any) {
    formatTime(el, binding);
  }
};
// 检核权限
const permissionDirective = {
  mounted(el: any, binding: any) {
    checkPermission(el, binding);
  }
};
//解决表格中单元格高度与同行不一致问题
const fixCellHeightDirective = {
  mounted(el: any, binding: any) {
    fixCellHeight(el, binding);
  },
  updated(el: any, binding: any) {
    fixCellHeight(el, binding);
  }
};
// 拖拽排序
const dragSortDirective = {
  mounted(el: any, binding: any) {
    dragSort(el, binding);
  },
  updated(el: any, binding: any) {
    dragSort(el, binding);
  }
};
//占位隐藏 false:隐藏 true:显示
const visibilityHiddenDirective = {
  mounted(el: any, binding: any) {
    visibilityHidden(el, binding);
  },
  updated(el: any, binding: any) {
    visibilityHidden(el, binding);
  }
};
//解决多选下拉框高度不能撑开问题
const fixMultipleSelectHeightDirective = {
  mounted(el: any) {
    fixMultipleSelectHeight(el);
  },
  updated(el: any) {
    fixMultipleSelectHeight(el);
  }
};

export default {
  install(app: any) {
    // 示例：<span v-formatTime="{ value: scope.row.addDateTime, type: 'dateTime' }" />
    app.directive("formatTime", formatTimeDirective);
    // 示例:<el-button v-permission:B="1" type="primary" @click="addRecord" class="button-add"> 新增</el-button>
    app.directive("permission", permissionDirective);
    // 示例:<draggable class="drag" v-fixCellHeight="'drag'">
    // drag 为el-table-columne自定义内容插槽DOM class名
    app.directive("fixCellHeight", fixCellHeightDirective);
    // 解决多选下拉框高度不能撑开问题
    app.directive("fixMultipleSelectHeight", fixMultipleSelectHeightDirective);
    app.directive("focus", {
      mounted(el: any) {
        const dom = el.querySelector("input") || el.querySelector("textarea");
        dom?.focus();
      }
    });
    // 示例：<div v-dragSort="{ el: '.el-table__body-wrapper tbody', handleClass: '.drag-handle', callBack: ()=>{} }"></div>
    app.directive("dragSort", dragSortDirective);
    // 占位隐藏
    // v-visibilityHidden="false" false:隐藏 true:显示
    app.directive("visibilityHidden", visibilityHiddenDirective);
  }
};
